from django.db.models import Q
from django.conf import settings
from django.http import JsonResponse
from rest_framework.views import APIView
from .models import Menu
from role.models import RoleMenu
from .validate import AddValidate, EditValidate
from utils.utils import responseSuccess, responseError, validateError, serializerJSON, filterFields
from .serializers import RoutesSerializer, MenuLazyListSerializer, MenuTreeSerializer, DetailSerializer, GrantTreeSerializer

# 获取菜单管理-菜单表格数据
class LazyListAPI(APIView):
    def get(self,req):
        queryDict = req.query_params.dict()
        if queryDict.get('parentId') == '0':
            # 获取顶级菜单
            queryDict['parentId'] = None
        else:
            queryDict = filterFields(Menu, queryDict)
        menus = Menu.objects.filter(**queryDict)
        serializers = MenuLazyListSerializer(menus, many=True, context={'exclude': ['hasChildren']})
        datas = serializerJSON(serializers)
        return JsonResponse(responseSuccess(datas), safe=False)

# 获取菜单管理-新增弹窗中“上级菜单”下拉列表数据
class TreeAPI(APIView):
    def get(self, req):
        serializers = MenuTreeSerializer(Menu.objects.filter(parentId=None), many=True, context={'fields': ['id', 'name', 'children']})
        datas = serializerJSON(serializers)
        return JsonResponse(responseSuccess(datas), safe=False)

# 系统管理-角色管理-角色权限配置
class GrantTreeAPI(APIView):
    def get(self,req):
        serializers = GrantTreeSerializer(Menu.objects.filter(parentId=None).all(), many=True, context={'fields': ['id', 'name', 'children']})
        datas = serializerJSON(serializers)
        return JsonResponse(responseSuccess(datas), safe=False)

# 系统管理-角色管理-获取指定角色绑定的菜单id列表
class RoleTreeKeysAPI(APIView):
    def get(self,req):
        queryDict = req.query_params.dict()
        roleIds = queryDict.get("roleIds")
        menuIds = RoleMenu.objects.only('menu_id').filter(role_id=int(roleIds)).values_list('menu_id', flat=True)
        menuIds = [str(i) for i in menuIds]
        return JsonResponse(responseSuccess(menuIds), safe=False)

# 获取路由菜单
class RoutesAPI(APIView):
    def get(self, req):
        q = Q(parentId=None)
        # 根据用户角色获取关联的所有顶级菜单id
        topMenuIds = set()
        # 根据用户角色权限获取关联的所有菜单id
        menuIds = set()
        # 超级管理员不过滤菜单
        if not req.user.userrole_set.filter(role__roleAlias=settings.ROLE['superadmin']).exists():
            for user_role in req.user.userrole_set.all():
                for i in user_role.role.rolemenu_set.all():
                    menuIds.add(i.menu_id)
                    topMenuIds.add(i.menu.parentId_id)
            q &= Q(id__in=topMenuIds)
        objs = Menu.objects.filter(q)
        serializers = RoutesSerializer(objs, many=True, context={"menuIds": menuIds})
        datas = serializerJSON(serializers)
        return JsonResponse(responseSuccess(datas), safe=False)

# 获取详情
class DetailAPI(APIView):
    def get(self, req):
        id = req.query_params.dict().get("id")
        if not id:
            return JsonResponse(responseError('请指定id'), safe=False)
        serializer = DetailSerializer(Menu.objects.get(pk=id))
        return JsonResponse(responseSuccess(serializer.data), safe=False)

# 菜单新增/修改
class SubmitAPI(APIView):
    def post(self,req):
        data = req.data
        edit_id = data.get('id')
        if edit_id:
            menu = Menu.objects.get(id=int(edit_id))
            form = EditValidate(menu, data=data)
        else:
            form = AddValidate(data=data)
        if form.is_valid():
            if edit_id:
                obj = form.update(menu, form.validated_data)
            else:
                obj = form.create(form.validated_data)
            return JsonResponse(responseSuccess(str(obj.pk)), safe=False)
        # 格式化错误信息
        arr = validateError(form.errors)
        return JsonResponse(responseError(arr), safe=False)

# 删除菜单
class RemoveAPI(APIView):
    def post(self,req):
        ids = req.query_params.dict().get('ids')
        if not ids:
            return JsonResponse(responseError('ids不能为空'), safe=False)
        ids = ids.split(',')
        if not Menu.objects.filter(id__in=ids).exists():
            return JsonResponse(responseError('删除对象不存在'), safe=False)
        for i in Menu.objects.filter(id__in=ids):
            if i.menu_set.exists():
                return JsonResponse(responseError('请先删除子菜单'), safe=False)
        result = Menu.objects.filter(id__in=ids).delete()
        if result:
            return JsonResponse(responseSuccess(), safe=False)
        return JsonResponse(responseError('删除失败'), safe=False)

# 获取顶部菜单（暂时没用）
class TopMenuAPI(APIView):
    def get(self, req):
        return JsonResponse(responseSuccess(), safe=False)

# 根据用户角色获取关联菜单中按钮
class ButtonsAPI(APIView):
    def get(self, req):
        roleIds = req.user.userrole_set.only('role_id').values_list('role',flat=True)
        datas = []
        if len(roleIds):
            menuIds = set(RoleMenu.objects.only('role_id','menu_id').filter(role_id__in=roleIds).values_list('menu_id',flat=True))
            if len(menuIds):
                menus = Menu.objects.only('id','category','code').filter(parentId_id__in=menuIds, category=2).values_list('code',flat=True)
                datas = [menu for menu in menus]
        return JsonResponse(responseSuccess(datas), safe=False)

